package top.xphu.zip.service;

import okhttp3.OkHttpClient;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import top.xphu.zip.entiy.Param;
import top.xphu.zip.entiy.ZFileInputStream;
import top.xphu.zip.enums.HttpMethod;
import top.xphu.zip.enums.ParamType;
import top.xphu.zip.service.impl.DownloadFileImpl;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;

/**
 * @author xphu
 * @version 1.0
 * @date 2021/7/1 16:01
 */
public abstract class DownloadFile{

    /**
     * http请求实例对象
     */
    protected OkHttpClient httpClient;

    public static DownloadFile build(){
        return new DownloadFileImpl();
    }

    /**
     * 下载文件
     * @param file 要下载的file文件
     * @param fileName 文件名称（不传值则使用默认的名称）
     * @param response  javax.servlet.http.HttpServletResponse
     * @return response javax.servlet.http.HttpServletResponse;
     * @throws Exception
     */
    public HttpServletResponse download(File file,String fileName, HttpServletResponse response) throws Exception {
        if (!file.exists()){
            throw new Exception("压缩文件不存在");
        }
        if (StringUtils.isEmpty(fileName)){
            fileName = file.getName();
        }
        //缓冲输出流
        BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
        response.setContentType("application/x-zip-compressed");
        // 防止输出的是中文名
        response.setHeader("Content-Disposition", "attachment;filename="
                + new String(fileName.getBytes("GB2312"), "ISO8859-1"));
        // 以流的形式下载文件。
        InputStream fis = new FileInputStream(file.getPath());
        try{
            byte[] buffer = new byte[1024];
            int i = 0;
            while ((i = fis.read(buffer)) != -1){
                outputStream.write(buffer, 0, i);
            }
        }catch (Exception e){
            e.printStackTrace();
        } finally {
            try{
                if (file.exists()){
                    file.delete();
                }
                if (outputStream != null){
                    outputStream.flush();
                    outputStream.close();
                }
                if (fis != null){
                    fis.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return response;
    }

    /**
     * 下载文件
     * @param fis 要下载的file文件流
     * @param fileName 文件名称（不传值则使用默认的名称）
     * @param response  javax.servlet.http.HttpServletResponse
     * @return response javax.servlet.http.HttpServletResponse;
     * @throws Exception
     */
    public HttpServletResponse download(InputStream fis, String fileName, HttpServletResponse response) throws Exception {
        if (fis == null){
            throw new Exception("压缩文件不存在");
        }
        try{
            if (StringUtils.isEmpty(fileName)){
                fileName = "default.zip";
            }
            // 设置ContentType、文件名称和编码格式
            response.setContentType("application/x-zip-compressed");
            // 如果输出的是中文名
            response.setHeader("Content-Disposition", "attachment;filename="
                    + new String(fileName.getBytes("GB2312"), "ISO8859-1"));

            // 以流的形式下载文件。
            byte[] buffer = new byte[512];
            int i = 0;
            ServletOutputStream outputStream = response.getOutputStream();
//            BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            while (( i = fis.read(buffer)) != -1){
                // 写数据关闭流
                outputStream.write(buffer, 0, i);
            }
            outputStream.flush();
            outputStream.close();
            fis.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        return response;
    }

    /**
     * 下载文件
     * @param zfis top.xphu.zip.entiy.ZFileInputStream
     * @param response  javax.servlet.http.HttpServletResponse
     * @return response javax.servlet.http.HttpServletResponse;
     * @throws Exception
     */
    public HttpServletResponse download(ZFileInputStream zfis, HttpServletResponse response) throws Exception {

        if (ZFileInputStream.isNotNull(zfis)){
            throw new Exception("压缩文件不存在");
        }
        InputStream fis = zfis.getFileBody();
        String fileName = zfis.getFileName();

        try{
            if (StringUtils.isEmpty(fileName)){
                fileName = "default.zip";
            }
            // 设置ContentType、文件名称和编码格式
            response.setContentType("application/x-zip-compressed");
            // 如果输出的是中文名
            response.setHeader("Content-Disposition", "attachment;filename="
                    + new String(fileName.getBytes("GB2312"), "ISO8859-1"));

//            ServletOutputStream outputStream = response.getOutputStream();
            BufferedOutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            // 以流的形式下载文件。
            byte[] buffer = new byte[512];
            int i = 0;
            while (( i = fis.read(buffer)) != -1){
                // 写数据关闭流
                outputStream.write(buffer, 0, i);
            }
            outputStream.flush();
            outputStream.close();
            fis.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        return response;
    }


    public abstract HttpServletResponse execute(String fileName , Response response, HttpServletResponse httpResponse) throws Exception;

    /**
     * 执行下载
     * @param fileName
     * @param response
     * @param httpResponse
     * @return
     * @throws Exception
     */
    public abstract ZFileInputStream executeToFileInputStream(String fileName , Response response, HttpServletResponse httpResponse) throws Exception;

    /**
     *
     * @param url 下载地址
     * @param fileName 文件名
     * @param response HttpServletResponse
     * @return HttpServletResponse
     * @throws Exception
     */
    public abstract HttpServletResponse httpDownload(String url, String fileName, HttpServletResponse response) throws Exception;


    /**
     *
     * @param url 下载地址
     * @param fileName 文件名
     * @param param 参数
     * @param paramType 参数类型
     * @param response HttpServletResponse
     * @return HttpServletResponse
     * @throws Exception
     */
    public abstract HttpServletResponse httpDownload(String url, String fileName, Map<String, String> param, ParamType paramType, HttpServletResponse response) throws Exception;


    /**
     *
     * @param url 下载地址
     * @param fileName 文件名
     * @param param 参数
     * @param paramType 参数类型
     * @param response HttpServletResponse
     * @return HttpServletResponse
     * @param method 请求方式
     * @return HttpServletResponse
     */
    public abstract HttpServletResponse httpDownload(String url, HttpMethod method, String fileName, Map<String, String> param, ParamType paramType, HttpServletResponse response) throws Exception;

    /**
     * @param url       下载地址
     * @param method    请求方式
     * @param fileName
     * @param param
     * @param paramType
     * @param response
     * @return HttpServletResponse
     */
    public abstract HttpServletResponse httpDownload(String url, HttpMethod method, String fileName, Param param, ParamType paramType, HttpServletResponse response) throws Exception;

    /**
     * 通过get http请求下载文件
     * @param url       下载地址 "http://www.5m4.top/file/15"
     * @param fileName  文件名称 ：default.txt
     * @param httpResponse
     * @return HttpServletResponse
     */
    public abstract HttpServletResponse doGetHttpDownload(String url, String fileName, HttpServletResponse httpResponse) throws Exception;

    /**
     * 通过get http请求下载文件
     * @param url 下载地址
     * @param fileName 文件名
     * @param param 参数
     * @param response HttpServletResponse
     * @return HttpServletResponse
     */
    public abstract  HttpServletResponse doGetHttpDownload(String url, String fileName, Map<String, String> param, HttpServletResponse response) throws Exception;


    /**
     * 通过post http请求下载文件
     *
     * @param url   下载地址
     * @return HttpServletResponse
     */
    public abstract HttpServletResponse doPostHttpDownload(String url, String fileName, HttpServletResponse httpResponse) throws Exception;

    /**
     * 通过post http请求下载文件
     * @param url 下载地址
     * @param param 参数
     * @param fileName 文件名
     * @param param 参数
     * @param paramType 参数类型
     * @param response HttpServletResponse
     * @return HttpServletResponse
     */
    public abstract HttpServletResponse doPostHttpDownload(String url, String fileName, Map<String, String> param, ParamType paramType, HttpServletResponse response) throws Exception;


    /**
     * 通过get http请求下载文件
     * @param url 下载地址
     * @param fileName 文件名
     * @param param 参数
     * @param response HttpServletResponse
     * @return HttpServletResponse
     */
    public abstract HttpServletResponse doGetHttpDownload(String url, String fileName, Param param, HttpServletResponse response) throws Exception;

    /**
     * 通过post http请求下载文件
     * @param url 下载地址
     * @param param 参数
     * @param fileName 文件名
     * @param param 参数
     * @param paramType 参数类型
     * @param response HttpServletResponse
     * @return HttpServletResponse
     */
    public abstract HttpServletResponse doPostHttpDownload(String url, String fileName, Param param,ParamType paramType, HttpServletResponse response) throws Exception;


    public abstract ZFileInputStream doGetHttpDownloadToZFileInputStream(String url, String fileName, HttpServletResponse httpResponse) throws Exception;

}
